﻿using System;
using System.Collections.Generic;

namespace PhoobearLibs.Resource.Resx
{
   
    /// <summary>
    /// 리소스 파일을 표현하는 기본 클래스
    /// </summary>
    /// <typeparam name="T">Value의 타입</typeparam>
    public abstract class ResourceFile<TValue> : Resource<TValue>
    {

#region Public Property
        
        /// <summary>
        /// 파일 경로 
        /// </summary>
        private string _filePath = string.Empty;
        public string Path
        {
            get
            {
                return _filePath;
            }

            set
            {
                if (this.IsCorrectExtension(value) == true)
                {
                    _filePath = value;
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Invalid File Extension {0}", value));
                }
            }
        }

        /// <summary>
        /// 내부 리소스 데이터 
        /// </summary>       
        public override Dictionary<string, TValue> Data
        {
            get
            {
                if (base.Data == null)
                {
                    base.Data = this.LoadData(this.Path);
                }
                return base.Data;
            }

            protected set
            {
                base.Data = value;                
            }
        }

      
#endregion
        
#region Protected Methods
 
        /// <summary>
        /// 해당 파일의 확장자가 맞는지 확인합니다.
        /// </summary>
        /// <param name="path">파일경로</param>
        /// <param name="extension">확장</param>
        /// <returns>확장자가 제대로 되었는지 확인</returns>
        protected abstract bool IsCorrectExtension(string path);

        /// <summary>
        /// 데이터를 읽어 로드합니다. 
        /// </summary>
        /// <param name="path">파일 경로</param>
        /// <returns>파일로부터 읽은 리소스 데이터</returns>
        protected abstract Dictionary<string, TValue> LoadData(string path);

        /// <summary>
        /// 데이터를 지정된 경로에 저장합니다.
        /// </summary>        
        /// <param name="path">파일 경로</param>
        /// <returns>저장성공여부</returns>
        protected abstract bool SaveData(string path);
      
#endregion
                
#region Public Methods


        /// <summary>
        /// 이 파일의 문자열 형태 표현을 반환합니다.
        /// </summary>
        /// <returns>이 리소스 파일의 문자열 정의</returns>
        public override string ToString()
        {
            return this.Path;
        }
        
        /// <summary>
        /// 아무것도 없는 새로운 파일을 생성합니다. 
        /// </summary>
        /// <param name="path">새 파일의 경로</param>
        /// <returns>정상적으로 파일이 생성되었는지 아닌지 여부</returns>
        public void New(string path)
        {
            this.Path = path;
            this.Data = new Dictionary<string, TValue>();
        }

        #region IEquatable<ResourceFile> 멤버

        /// <summary>
        /// 두 객체가 동일한지 검사
        /// </summary>
        /// <param name="other">비교할 객체</param>
        /// <returns>동일하면 true 틀리면 false</returns>
        public override bool Equals(Resource<TValue> other)
        {
            bool isPathEquals = false;

            ResourceFile<TValue> otherFile = other as ResourceFile<TValue>;
            if (otherFile != null)
            {
                isPathEquals = this.Path.Equals(otherFile.Path);
            }
            
            bool isDataEquals = base.Equals(otherFile);

            return isPathEquals && isDataEquals;
        }

        #endregion

        /// <summary>
        /// 로드한 파일 저장
        /// </summary>
        /// <param name="path">저장할 새 경로</param>
        /// <returns>정상적으로 저장되었는지 여부</returns>
        public bool Save(string path)
        {
            return this.SaveData(this.Path);
        }

        /// <summary>
        /// 로드한 파일 저장
        /// </summary>
        /// <returns>정상적으로 저장되었는지 여부</returns>
        public bool Save()
        {
            return this.Save(this.Path);
        }    

#endregion

    }
}
